<?php


	namespace Midi\Parsing;
	
	use \Midi\Util\Util;
	use \SplFileObject;

	abstract class Parser {
		
		private $state;
		
		protected $file;
		
		public function __construct() {
			$this->file  = null;
			$this->state = ParseState::EOF;
		}
		
		public function createFileObject($file) {
			return new SplFileObject($file, 'rb');
		}
		
		public function load($file) {
			if (!($file instanceof SplFileObject)) {
				$file = $this->createFileObject($file);
			}
			
			$this->file = $file;
			$this->afterLoad();
		}
		
		public function setFile(SplFileObject $file) {
			$this->file = $file;
			$this->afterSetFile();
		}
		
		public function getState() {
			return $this->state;
		}
		
		protected function setState($state) {
			$this->state = $state;
		}
		
		protected function read($count, $throwOnEof = false) {
			$data = null;
			while ($this->file->valid() && $count--) {
				$data .= $this->file->fgetc();
			}
			
			if ($count > 0 && $throwOnEof) {
				throw new ParseException('Unexpected EOF');
			}
			
			return $data;
		}
		
		protected function getDelta() {
			$byte = $this->read(1, true);
			$value = Util::unpack($byte);
			$delta = '';
			while ($this->file->valid() && $value[0] > 0x7F) {
				$delta .= $byte;
				$byte   = $this->read(1);
				$value  = Util::unpack($byte);
			}
			
			if ($byte !== null) {
				$delta .= $byte;
			}
			
			return Util::getTicksFromDeltaByteSequence($delta);
		}
		
		protected function afterLoad() {
		
		}
		
		protected function afterSetFile() {
		
		}
		
		public abstract function parse();
		
	}

?>